package com.niiwoo.civet.trade.service.dubbo.cardniu;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.niiwoo.civet.trade.dao.entity.ProjectBorrowerSummary;
import com.niiwoo.civet.trade.dao.entity.ProjectLendRecord;
import com.niiwoo.civet.trade.dao.mapper.ProjectBorrowerPlanNewMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectBorrowerSummaryMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectLendRecordMapperExt;
import com.niiwoo.civet.trade.dto.ProjectBorrowerPlanNewDTO;
import com.niiwoo.civet.trade.dto.common.CardNiuLoanResult;
import com.niiwoo.civet.trade.dto.common.ProjectDTO;
import com.niiwoo.civet.trade.dto.common.ProjectSummaryDTO;
import com.niiwoo.civet.trade.dto.response.cardniu.CardNiuLoanCreditAmountDTO;
import com.niiwoo.civet.trade.dto.response.cardniu.CardniuLoanConfigDTO;
import com.niiwoo.civet.trade.dto.response.cardniu.RepayPlanInfo;
import com.niiwoo.civet.trade.enums.TradeConfigEnum;
import com.niiwoo.civet.trade.service.cardniu.CardNiuLoanDubboService;
import com.niiwoo.civet.trade.service.local.cardniu.CardNiuLoanLocalService;
import com.niiwoo.civet.trade.service.local.cardniu.CardNiuRefundLocalService;
import com.niiwoo.civet.trade.service.local.configure.TradeConfigLocalService;
import com.niiwoo.civet.trade.service.local.project.ProjectLocalService;
import com.niiwoo.civet.user.dto.response.cardniu.CardNiuCreditInfoDTO;
import com.niiwoo.civet.user.service.asset.AssetCreditDubboService;
import com.niiwoo.tripod.provider.exception.BizException;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.FastDateFormat;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Created by dell on 2018/2/24.
 * Description：civet-app
 */
@Slf4j
@Service(version = "1.0.0",validation = "true")
public class CardNiuLoanDubboServiceImpl implements CardNiuLoanDubboService {

    @Reference(version = "1.0.0")
    private AssetCreditDubboService assetCreditDubboService;

    @Autowired
    private CardNiuLoanLocalService loanLocalService;

    @Autowired
    private TradeConfigLocalService tradeConfigLocalService;

    @Autowired
    private ProjectLendRecordMapperExt projectLendRecordMapperExt;

    @Autowired
    private ProjectBorrowerPlanNewMapperExt projectBorrowerPlanNewMapper;

    @Autowired
    private ProjectBorrowerSummaryMapperExt projectBorrowerSummaryMapperExt;

    @Autowired
    private CardNiuRefundLocalService cardNiuRefundLocalService;

    @Autowired
    private ProjectLocalService projectLocalService;

    /**
     * 获取用户卡牛的授信额度
     * @param userId
     * @return
     */
    @Override
    public CardNiuLoanCreditAmountDTO getCardNiuLoanCreditAmount(String userId) {

        return getCardNiuLoanCreditAmountDTO(userId);
    }

    @Override
    public CardniuLoanConfigDTO getCardniuLoanConfig(String userId) {
        // 借款配置和费率信息
        CardniuLoanConfigDTO cardniuLoanConfigDTO = loanLocalService.getCardniuLoanConfig();
        // 借款配置
        Map<String, String> configMap = tradeConfigLocalService.selectTradeConfigByEmuns(TradeConfigEnum.CARDNIU_MINAMOUNT, TradeConfigEnum.CARDNIU_MAXAMOUNT, TradeConfigEnum.CARDNIU_UPDATECREDITLINE,TradeConfigEnum.CARDNIU_HITCREDITMODELLIMITDAYS);
        cardniuLoanConfigDTO.setMinAmount(new BigDecimal(configMap.get(TradeConfigEnum.CARDNIU_MINAMOUNT.getConfigKey())));
        cardniuLoanConfigDTO.setTermUnit((byte) 2);
        cardniuLoanConfigDTO.setLimitDays(Integer.valueOf(configMap.get(TradeConfigEnum.CARDNIU_HITCREDITMODELLIMITDAYS.getConfigKey())));
        // 额度信息
        BigDecimal usedAmount = loanLocalService.getCardNiuUsedCredit(userId); // 已使用额度
        cardniuLoanConfigDTO.setUsedAvailable(usedAmount);
        DateTime expirationDate = new DateTime().plusDays(Integer.valueOf(configMap.get(TradeConfigEnum.CARDNIU_UPDATECREDITLINE.getConfigKey())));
        cardniuLoanConfigDTO.setExpirationDate(FastDateFormat.getInstance("yyyyMMdd").format(expirationDate.toDate())); // 额度有效期

        return cardniuLoanConfigDTO;
    }

    private CardNiuLoanCreditAmountDTO getCardNiuLoanCreditAmountDTO(String userId) {
        CardNiuLoanCreditAmountDTO cardNiuLoanCreditAmountDTO = new CardNiuLoanCreditAmountDTO();

        //获取用户额度信息
        CardNiuCreditInfoDTO userCardNiuCreditInfo = assetCreditDubboService.getUserCardNiuCreditInfo(userId);
        BigDecimal creditAmount = userCardNiuCreditInfo.getCreditTotalAmount();
        if (creditAmount != null) {
            Map<String, String> configMap = tradeConfigLocalService.selectTradeConfigByEmuns(TradeConfigEnum.CARDNIU_MAXAMOUNT);
            BigDecimal maxAmount = new BigDecimal(configMap.get(TradeConfigEnum.CARDNIU_MAXAMOUNT.getConfigKey()));
            cardNiuLoanCreditAmountDTO.setCreditTotalAmount(creditAmount.min(maxAmount));
            BigDecimal usedAmount = loanLocalService.getCardNiuUsedCredit(userId); // 已使用额度
            if (usedAmount != null) {
                cardNiuLoanCreditAmountDTO.setCreditUsedAmount(usedAmount);
            }
        } else {
            cardNiuLoanCreditAmountDTO.setCreditTotalAmount(BigDecimal.ZERO);
            cardNiuLoanCreditAmountDTO.setCreditUsedAmount(BigDecimal.ZERO);
        }

        return cardNiuLoanCreditAmountDTO;
    }

    /**
     * 卡牛借款成功前的数据
     * @param userId
     * @param projectId
     * @return
     */
    @Override
    public CardNiuLoanResult getLoanBeforeSuccess(String userId, Long projectId) {
        CardNiuLoanResult cardNiuLoanResult = new CardNiuLoanResult();
        try {
            //获取授信额度
            CardNiuLoanCreditAmountDTO cardNiuLoanCreditAmount = getCardNiuLoanCreditAmount(userId);
            //计算剩余额度
            BigDecimal creditLimitAvailable = cardNiuLoanCreditAmount.getCreditTotalAmount().subtract(cardNiuLoanCreditAmount.getCreditUsedAmount());
            cardNiuLoanResult.setCreditLimitAvailable(creditLimitAvailable);

            //用户当前标的待还总金额
            if(projectId != null) {
                BigDecimal shouldRepayAmount = cardNiuRefundLocalService.queryShouldRepayAmount(projectId);
                cardNiuLoanResult.setTotalAmount(shouldRepayAmount);
            }else {
                cardNiuLoanResult.setTotalAmount(BigDecimal.ZERO);
            }
        } catch (Exception e) {
            log.error("getLoanBeforeSuccess userId:{} projectId:{} 异常:{}", userId, projectId, e);
        }
        return cardNiuLoanResult;
    }

    @Override
    public ProjectSummaryDTO querySummaryInfoByProjectId(Long projectId) {
    	ProjectSummaryDTO summaryDTO = new ProjectSummaryDTO();
    	
		ProjectDTO projectDTO = projectLocalService.selectProjectById(projectId);
		
		// 查询订单不存在直接返回
		if (null == projectDTO) {
			return summaryDTO;
		}
		
		BigDecimal toRepayTotalAmount = BigDecimal.ZERO; // 待还总金额
		BigDecimal refundedTotalAmount = BigDecimal.ZERO; // 已还款总金额
		
		// 放款记录
		ProjectLendRecord projectLendRecord = projectLendRecordMapperExt.querySuccessLendRecordByProjectId(projectId);
		
		// 获取标的还款概要信息
		ProjectBorrowerSummary summary = projectBorrowerSummaryMapperExt.selectByPrimaryKey(projectId);
        
		// 查询所有还款计划
		List<ProjectBorrowerPlanNewDTO> projectBorrowerPlanNewDTOList = Optional.ofNullable(projectBorrowerPlanNewMapper.selectByProjectIdForAmount(projectId))
				.orElseThrow(() -> new BizException("TRD20005"));
		for (ProjectBorrowerPlanNewDTO projectBorrowerPlanNewDTO : projectBorrowerPlanNewDTOList) {
			toRepayTotalAmount = toRepayTotalAmount.add(projectBorrowerPlanNewDTO.getCapital()).add(projectBorrowerPlanNewDTO.getInterest())
					.add(projectBorrowerPlanNewDTO.getPenaltyFee()).add(projectBorrowerPlanNewDTO.getManagementFee()).add(projectBorrowerPlanNewDTO.getGuaranteeFee());
			refundedTotalAmount = (projectBorrowerPlanNewDTO.getRefundedCapital()).add(projectBorrowerPlanNewDTO.getRefundedInterest())
					.add(projectBorrowerPlanNewDTO.getRefundedPenaltyFee()).add(projectBorrowerPlanNewDTO.getRefundedManagementFee())
					.add(projectBorrowerPlanNewDTO.getRefundedGuaranteeFee());
		}
		if (projectLendRecord != null) {
			summaryDTO.setLoanTime(projectLendRecord.getUpdateTime());
			summaryDTO.setTotalLoan(projectDTO.getHandAmount());
		}
		if (summary.getCurrentPeriod().intValue() > 1) {
			summaryDTO.setRepayPlanVersionTime(summary.getUpdateTime());
		}
		summaryDTO.setFinishPeriod(summary.getCurrentPeriod() - 1);
		summaryDTO.setPaidAmount(refundedTotalAmount);
		summaryDTO.setTotalAmount(toRepayTotalAmount);
		summaryDTO.setChannelCode(projectDTO.getChannelCode());
		summaryDTO.setTotalPeriod(summary.getTotalPeriod());
		
        List<RepayPlanInfo> planInfoList = cardNiuRefundLocalService.queryRepayPlanInfo(projectBorrowerPlanNewDTOList, summary);
        summaryDTO.setPlanInfoList(planInfoList);
        return summaryDTO;
    }

    /**
     * 获取用户可用授信额度
     * @param userId
     * @return
     */
    @Override
    public BigDecimal getCardNiuUsedCredit(String userId){
        return loanLocalService.getCardNiuUsedCredit(userId);
    }

}
